package chinaums.service.impl;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CountDownLatch;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import chinaums.common.util.Crypt;
import chinaums.common.util.HttpUtils;
import chinaums.common.util.RespRecord;
import chinaums.common.util.SequenceUtil;
import chinaums.common.util.SptomlinkRecord;
import chinaums.dao.SptomlinkMapper;
import chinaums.entity.GetQrsmsNumbers;
import chinaums.entity.Sptomlink;
import chinaums.entity.Url;
import chinaums.service.IGetQrsmsListService;
import chinaums.service.IGetQrsmsNumbersService;
import chinaums.service.ISptomlinkService;
import chinaums.service.IUrlService;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;

/**
 * <p>Title:SptomlinkRunnable</p>
 * <p>Description:短信发送的runnable类</p>
 * @version v1.0
 * @author RenLei
 * 2017年7月21日
 */
public class SptomlinkRunnable extends Thread{
	private String mtUrl;
	private List<GetQrsmsNumbers> getQrsmsNumbersList;
	private CountDownLatch countDownLatch;
	private IGetQrsmsNumbersService getQrsmsNumbersService;
	private IGetQrsmsListService qrsmslistService;
	private IUrlService urlservice;
	private ISptomlinkService iSptomlinkService;
	private SptomlinkMapper ismMapper;
    public SptomlinkRunnable(List<GetQrsmsNumbers> getQrsmsNumbersList
    		                ,CountDownLatch countDownLatch
    		                ,IGetQrsmsNumbersService getQrsmsNumbersService
    		                ,IGetQrsmsListService qrsmslistService
    		                ,ISptomlinkService iSptomlinkService
    		                ,IUrlService urlservice
    		                ,String mtUrl
    		                ,SptomlinkMapper ismMapper
    		                 ){
    	this.countDownLatch=countDownLatch;
    	this.getQrsmsNumbersService=getQrsmsNumbersService;
    	this.getQrsmsNumbersList=getQrsmsNumbersList;
    	this.qrsmslistService=qrsmslistService;
    	this.iSptomlinkService=iSptomlinkService;
    	this.urlservice=urlservice;
    	this.mtUrl=mtUrl;
    	this.ismMapper=ismMapper;
    }
    private static Logger log= LoggerFactory
			.getLogger(SptomlinkRunnable.class);
	@Override
	public void run() {
		//System.out.println("run方法执行了.......");
		log.info(Thread.currentThread().getName()+"开始进行操作");
		try {
			List<Sptomlink> sList=new ArrayList<Sptomlink>();
			//分割数据
			List<GetQrsmsNumbers> getList=null;
			//获取集合大小
			int getotherList=getQrsmsNumbersList.size();
			//定义count数量
			int getCount=200;
			//定义循环次数
			int getTimeCount=0;
			//当小于count数量则只循环一次，count等于集合大小
			if(getotherList<=getCount){
				getTimeCount=1;
				getCount=getotherList;
			}else{
				getTimeCount=(getotherList/getCount)+1;
			}
			//将数据进行分页
			for (int pageNum = 1; pageNum < getTimeCount + 1; pageNum++)
			{
				int starNum = (pageNum - 1) * getCount;
				int endNum = pageNum * getCount > getotherList ? (getotherList) : pageNum * getCount;
				getList =getQrsmsNumbersList.subList(starNum,endNum);
				log.info(Thread.currentThread().getName()+"开始分页，页数是"+starNum+"到"+endNum+"大小是"+getList);
				//System.out.println("getList========="+getList.size());
				//再次分割数据
				List<GetQrsmsNumbers> newList=null;
				int otherList=getList.size();
				//控制数量
				int count=50;
				//定义循环次数
				int timeCount=0;
				//当小于count数量则只循环一次，count等于集合大小
				if(otherList<=count){
					count=otherList;
					timeCount=1;
				}else{
					if(otherList%count==0){
						timeCount=otherList/count;
					}else{
						timeCount=(otherList/count)+1;
					}
				}
				//将数据进行分页
				for (int i = 1; i < timeCount+1; i++) {
					int startIndex = (i - 1) * count;
					int endIndex = i * count > otherList ? (otherList) : i * count;
					newList =getList.subList(startIndex,endIndex);
					log.info(Thread.currentThread().getName()+"再次开始分页，页数是"+startIndex+"到"+endIndex+"大小是"+newList);
					//判断newList集合是否为空
					if(newList==null||newList.size()<=0){
						continue;
					}
					//System.out.println("newList======"+newList.size());
					
					//定义俩个Stringbuffer来接受手机号码和短信内容
					//短连接和短信内容的组合
					StringBuffer UrlContent=new StringBuffer();
					//单个手机号码集合
					StringBuffer sigPhone=new StringBuffer();
					//模板编号
					StringBuffer modelNo=new StringBuffer();
					//触发规则编号
					StringBuffer ruleId=new StringBuffer();
					
				
					Map<String, Object> map=null;
					List<Url> urlList=null;
					//遍历newList集合
					for (int l = 0; l < newList.size(); l++) {
						//先修改GetQrsmsNumbers表的状态根据Qrsms_ids
						GetQrsmsNumbers number=new GetQrsmsNumbers();
						number.setQrsms_ids(newList.get(l).getQrsms_ids());
						number.setVersion(newList.get(l).getVersion());
						//修改version和version根据ids
						int numberversion=getQrsmsNumbersService.updateversion(number);
						//如果修改失败，continue，说明该手机号码被其它线程取过
						if(numberversion==0){
							log.info("该手机号正被其它服务器执行!");
							continue;
						}
						//获取规则编号
						String ruleid=newList.get(l).getR_number();
						//获取手机号
						String phone=newList.get(l).getB_phone();
						log.info(Thread.currentThread().getName()+"开始遍历newList,第"+i+"次,手机号是"+phone+"触发规则是"+ruleid);
						//获取GetQrsmsNumbers表的时间
						Date currentime=newList.get(l).getCurrentime();
						//获取当前时间
						Date nowtime=new Date();
						long totaltime=(nowtime.getTime()-currentime.getTime())/1000/60;
						/*System.out.println("nowtime.getTime()--------------"+nowtime.getTime());
						System.out.println("currentime.getTime()--------------"+currentime.getTime());
						System.out.println("totaltime----------------"+totaltime);*/
						//判断表时间和当前时间之差，大于5分钟说明该数据已超时
						if((int)totaltime>10){
							log.info("该数据已过时");
							continue;
						}
						//根据触发规则编号查询qrsmslist表
						map = qrsmslistService.selectGetQrsmsList(ruleid);
						log.info(Thread.currentThread().getName()+"开始查询qrsmslist"+map);
						//判断手机号码和规则编号是否匹配qrsmslist表的数据
						if(map == null || map.size() <= 0){
							log.info("没有符合的数据");
							continue;
						}
						
						
						//获取模板编号
						String modNo="";
						//定义俩个变量来接受短信内容和手机号码
						String newsm ="";
						//userid=qrsmsList.get(j).getCustom_id();
						//获取模板编号
						modNo= map.get("templateId").toString();
						//获取该规则发送的总条数
						int total=iSptomlinkService.selectCountbyRuleid(ruleid);
						//获取发送总数量
						int allTotal=Integer.parseInt(map.get("all_send_cnt").toString());
						//判断该规则发送的总条数是否大于发送总数量
						if(total>=allTotal){
							//如果大于，则修改QrsmsList的状态为1
							Integer Id=Integer.parseInt(map.get("id").toString());
							qrsmslistService.updateGetQrsmsList(Id);
							log.info("超过总发送数量"+allTotal);
							continue;
						}
						//获取手机号发送数量
						int phoneCount=iSptomlinkService.count(phone);
						//获取手机号发送总数量
				        String sendCount=map.get("single_send_cnt").toString();
				        //判断手机号发送数量是否大于该手机号发送总数量
				        if(phoneCount>=Integer.parseInt(sendCount)){
				        	log.info("该手机号码已发过"+sendCount+"次");
				        	continue;
				        }
				        long nd = 1000 * 24 * 60 * 60;
				        long nh = 1000 * 60 * 60;
				        long nm = 1000 * 60;
				        // long ns = 1000;
				        // 获得两个时间的毫秒时间差异
				        //long diff = endDate.getTime() - nowDate.getTime();
				        // 计算差多少天
				        //long day = diff / nd;
				        // 计算差多少小时
				        //long hour = diff % nd / nh;
				        // 计算差多少分钟
				        //long min = diff % nd % nh / nm;
				        // 计算差多少秒//输出结果
				        // long sec = diff % nd % nh % nm / ns;
				        //获取手机发送时间间隔
				        Sptomlink timeList=iSptomlinkService.selectTime(phone);
				        if(timeList != null){
					        	//获取当前时间
					        	Date now = new Date();
					        	//获取Sptomlink表时间
					        	Date time = timeList.getTimeStamp();
						        long resultTime = (now.getTime()-time.getTime())/nm;
						        //获取限制时间
						        String between=map.get("single_send_cycle").toString();
						        //比较俩个时间之差是否大于限制时间
						        if((int)resultTime <= Integer.parseInt(between)){
						        	log.info(between+"分钟之内不能重复发同一个号码");
						        	continue;
						        }
				        }
				        //判断qrsmslist表中flag字段，2-数据损坏
				        if("2".equals(map.get("transform_flag").toString())){
							log.info("数据已损坏");
							continue;
						}
				        //判断qrsmslist表中flag字段，1-需要配置短连接
						if("1".equals(map.get("transform_flag").toString())){
								String shortUrl = null;
								//获取id
								Integer getId = Integer.parseInt(map.get("id").toString());
								//得到一条短链接
								urlList = urlservice.selectUrl(getId);
								if (urlList == null || urlList.size() <= 0) {
									log.info("没有相匹配的数据");
									continue;
								}
								for (int k = 0; k < urlList.size(); k++) {
									//获取到短链接
									shortUrl = urlList.get(k).getShorturl();
									if (shortUrl == null || "".equals(shortUrl)) {
										log.info("shorturl为空");
									}
									//替代短信内容中的${url}
									newsm =shortUrl;
									if (newsm == null || "".equals(newsm)) {
										log.info("newsm为空");
									}
									//修改url状态，说明该条数据已被取
									Url url = new Url();
									url.setUrlstate(1);
									url.setUrlid(urlList.get(k).getUrlid());
									url.setVersion(urlList.get(k).getVersion());
									int result = 0;
									result = urlservice.updateUrl(url);
									int num = 0;
									//如果修改失败，那么说明已有线程取过该条数据，需要重新取一条短连接给该手机号码
									while (result == 0) {
										//当循环到10次的时候还没有取到数据，则跳出循环
										if (num > 10) {
											break;
										}
										//从新得到一条短链接
										urlList = urlservice.selectUrl(getId);
										//获取到短链接
										shortUrl = urlList.get(k).getShorturl();
										//替代短信内容中的${url}
										newsm = shortUrl;
										//修改url状态
										Url url1 = new Url();
										url1.setUrlstate(1);
										url1.setUrlid(urlList.get(k).getUrlid());
										url1.setVersion(urlList.get(k)
												.getVersion());
										result = urlservice.updateUrl(url1);
										num = num + 1;
									}
								}
							}
						//判断qrsmslist表中flag字段，0-不需要配置短连接，当url为空时，则只需发送短信内容，否，就发送当前链接
						if("0".equals(map.get("transform_flag").toString())){
							//就发送当前链接
							if(map.get("url").toString()!=null||!"".equals(map.get("url").toString())){
								//获取当前链接
								String geturl=map.get("url").toString();
								//把url替换${}
								newsm=geturl;
							}else{
								newsm="";
							}
						}
						
						
					    //拼接规则编号
					    ruleId.append(ruleid);
					    if(l+1<newList.size()){
					    	ruleId.append("|");
						}
					    //拼接模板编号
					    modelNo.append(modNo);
					    if(l+1<newList.size()){
					    	modelNo.append("|");
						}
						//获取手机号集合
						sigPhone.append(phone);
						if(l+1<newList.size()){
							sigPhone.append("|");
						}
						//拼接短连接和短信内容
						UrlContent.append(newsm);
						if(l+1<newList.size()){
							UrlContent.append("|");
						}
						log.info(Thread.currentThread().getName()+"开始收集手机号"+sigPhone.toString());
							
							
						//修改数据状态根据ids
						GetQrsmsNumbers numbers=new GetQrsmsNumbers();
						numbers.setState("1");
						numbers.setQrsms_ids(newList.get(l).getQrsms_ids());
						int getQrsmsResult=getQrsmsNumbersService.updateQrsmsNumbers(numbers);
						log.info(Thread.currentThread().getName()+"开始修改手机和触发规则编号的表"+newList.get(l).getQrsms_ids()+"的结果为"+getQrsmsResult);
					    }
					
					
						//判断ruleID集合是否为空
					    if(ruleId.toString()==null||"".equals(ruleId.toString())){
							continue;
						}
					    //判断modelno集合是否为空
					    if(modelNo.toString()==null||"".equals(modelNo.toString())){
							continue;
						}
						//判断sigPhone的数组是否为空
						if(sigPhone.toString()==null||"".equals(sigPhone.toString())){
							continue;
						}
						//判断newPhone的数组是否为空
						if(UrlContent.toString()==null||"".equals(UrlContent.toString())){
							continue;
						}
						//log.info(Thread.currentThread().getName()+"userId是"+userId.toString());
						log.info(Thread.currentThread().getName()+"ruleId是"+ruleId.toString());
						log.info(Thread.currentThread().getName()+"modelNo是"+modelNo.toString());
						log.info(Thread.currentThread().getName()+"sigPhone是"+sigPhone.toString());
						log.info(Thread.currentThread().getName()+"UrlContent是"+UrlContent.toString());
						
						
						//userId
						String userId="8!";
						//生成流水号
						String transId=SequenceUtil.nextId();
						log.info(Thread.currentThread().getName()+"transId是"+transId);
						//生成时间戳
						Date timeStamp = new Date();
						SimpleDateFormat sdf=new SimpleDateFormat("yyyymmddhhmmss");
						String dateString = sdf.format(timeStamp);
						log.info(Thread.currentThread().getName()+"timeStamp是"+dateString);
						//生成mac
						StringBuffer sbMac=new StringBuffer();
						sbMac.append("userId");
						sbMac.append(userId);
						sbMac.append("transId");
						sbMac.append(transId);
						sbMac.append("timeStamp");
						sbMac.append(dateString);
						System.out.println("sbMac是:"+sbMac.toString());
						String temp=sbMac.toString();
						String mac=Crypt.encryptMD5(sbMac.toString());
						log.info(Thread.currentThread().getName()+"mac是"+mac);
						
						//将参数转为json
						SptomlinkRecord record=new SptomlinkRecord();
						record.setMac(mac);
						record.setPhone(sigPhone.toString());
						record.setTemplateId(modelNo.toString());
						record.setTemplateParams(UrlContent.toString());
						record.setTimeStamp(dateString);
						record.setTransId(transId);
						record.setUserId(userId);
						String jsonIn=String.valueOf(JSON.toJSON(record));
						log.info(Thread.currentThread().getName()+"jsonIn是"+jsonIn);
						
						//请求实时短信接口
						String response=HttpUtils.post(mtUrl, jsonIn);
						if(response==null||"".equals(response)){
							log.info("返回报文为空!");
							continue;
						}
						log.info(Thread.currentThread().getName()+"response是"+response);
						System.out.println(response);
						RespRecord respRecord=JSON.parseObject(response, RespRecord.class);
						
						//把ruleId转成String
						String ruleIdList=ruleId.toString();
						//把ruleId按|分割，用数组接收
						String[] newRuleId=ruleIdList.split("\\|");
						log.info(Thread.currentThread().getName()+"ruleIdList是"+ruleIdList);
						log.info(Thread.currentThread().getName()+"newRuleId长度是"+newRuleId.length);
						//把newRuleId封装到集合里去
						ArrayList<String> newRuleIdList=new ArrayList<String>();
						Collections.addAll(newRuleIdList, newRuleId);
						System.out.println("newRuleIdList==="+newRuleIdList.size());
						log.info(Thread.currentThread().getName()+"正在分割ruleid，大小为"+newRuleIdList.size());
						
						//把modelNo转成String
						String modelNoList=modelNo.toString();
						//把modelNoList按|分割，用数组接收
						String[] newModelNo=modelNoList.split("\\|");
						log.info(Thread.currentThread().getName()+"modelNoList是"+modelNoList);
						log.info(Thread.currentThread().getName()+"newModelNo长度是"+newModelNo.length);
						//把newModelNo封装到集合里去
						ArrayList<String> newModelNoList=new ArrayList<String>();
						Collections.addAll(newModelNoList, newModelNo);
						System.out.println("newModelNoList==="+newModelNoList.size());
						log.info(Thread.currentThread().getName()+"正在分割模板编号，大小为"+newModelNoList.size());
						
						//把UrlContent转成String
						String UrlContentList=UrlContent.toString();
						//把modelNoList按|分割，用数组接收
						String[] newUrlContent=UrlContentList.split("\\|");
						log.info(Thread.currentThread().getName()+"UrlContentList是"+UrlContentList);
						log.info(Thread.currentThread().getName()+"newUrlContent长度是"+newUrlContent.length);
						//把newModelNo封装到集合里去
						ArrayList<String> newUrlContentList=new ArrayList<String>();
						Collections.addAll(newUrlContentList, newUrlContent);
						System.out.println("newUrlContentList==="+newUrlContentList.size());
						log.info(Thread.currentThread().getName()+"正在分割短连接和短信，大小为"+newUrlContentList.size());
						
						
						//把sigPhone转成String
						String phoneList=sigPhone.toString();
						//把sigPhone按|分割，用数组接收
						String[] newSigPhone=phoneList.split("\\|");
						log.info(Thread.currentThread().getName()+"phoneList是"+phoneList);
						log.info(Thread.currentThread().getName()+"newSigPhone长度是"+newSigPhone.length);
						//把newsigPhone封装到集合里去
						ArrayList<String> newSigPhonelist=new ArrayList<String>();
						Collections.addAll(newSigPhonelist, newSigPhone);
						System.out.println("newsigPhonelist==="+newSigPhonelist.size());
						log.info(Thread.currentThread().getName()+"正在分割手机号，大小为"+newSigPhonelist.size());
						
						
						log.info("Code为:"+respRecord.getRespCode());
						log.info("Desc为:"+respRecord.getRespDesc());
						//遍历集合，一一对应添加
						for (int j = 0; j < newSigPhonelist.size(); j++) {
							//新增Sptomlink
							Sptomlink stm=new Sptomlink();
							stm.setRuleid(newRuleIdList.get(j));
							stm.setPhone(newSigPhonelist.get(j));
							stm.setTemplateId(newModelNoList.get(j));							//先判断参数所对应的下标是否为空，如果为空则给它默认为空
							if(newUrlContentList.get(j)==null||"".equals(newUrlContentList.get(j))){
								stm.setTemplateParams("");
							}else{
								stm.setTemplateParams(newUrlContentList.get(j));
							}
							stm.setTimeStamp(timeStamp);
							stm.setTransId(transId);
							stm.setUserId(userId);
							stm.setRespCode(respRecord.getRespCode());
							stm.setRespDesc(respRecord.getRespDesc());
							
							log.info(JSONObject.toJSONString(stm));
							sList.add(stm);//将Sptomlink添加到sList集合中
						}
						log.info("循环结束");
			     }
				//新增短信流水
				log.info("新增短信流水开始");
				ismMapper.addSptomlink(sList);
				log.info("正在插入短信表");
			}
		} catch (Exception e) {
			e.printStackTrace();
		}finally{
			//关闭辅助类线程
			countDownLatch.countDown();
		}
	}

}
